﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Felbot.Interaction;

namespace Felbot {
    /// <summary>This class represents the user entry manager form, where the user can add, edit, or remove user entries.</summary>
    public partial class frmCommandManager : Form {
        private XmlCommand m_Current;
        private List<string> m_Flags;
        private string m_OldLabel;
        private bool m_CommandSaved = true;

        /// <summary>
        /// Create a new user entry manager form.
        /// </summary>
        public frmCommandManager() {
            InitializeComponent();
        }

        private void frmCommandManager_Load(object sender, EventArgs e) {
            LoadEntryList();
        }

        private void LoadEntryList() {
            foreach (XmlCommand cmd in CommandControl.CommandList)
                lvCommands.Items.Add(new ListViewItem(cmd.Name));
        }

        private void lvCommands_SelectedIndexChanged(object sender, EventArgs e) {
            if (m_Current != null && !m_CommandSaved) {
                if (MessageBox.Show("The current command is not saved.\r\n" +
                                    "Do you want to save changes?",
                                    "Felbot",
                                    MessageBoxButtons.YesNo,
                                    MessageBoxIcon.Question,
                                    MessageBoxDefaultButton.Button1)
                        == DialogResult.Yes) {
                    SaveCurrentEntry();
                }
            }
            if (lvCommands.SelectedItems.Count == 1) {
                LoadCommand(lvCommands.SelectedItems[0].Text);
                pnlCmdEdit.Show();
                btnCmdSave.Show();
                btnCmdCancel.Show();
                lblInfo.Text = "Edit command " + m_Current.Name + ".";
            } else {
                m_Current = null;
                pnlCmdEdit.Hide();
                btnCmdSave.Hide();
                btnCmdCancel.Hide();
                lblInfo.Text = "Select a user entry to edit.";
            }
            btnCmdRemove.Enabled = (lvCommands.Items.Count > 0);
        }

        private void lvCommands_BeforeLabelEdit(object sender, LabelEditEventArgs e) {
            btnCmdRemove.Enabled = false;
            btnCmdAdd.Enabled = false;
            m_OldLabel = lvCommands.Items[e.Item].Text;
            pnlCmdEdit.Hide();
            btnCmdSave.Hide();
            btnCmdCancel.Hide();
            lblInfo.Text = "Edit command name for " + m_OldLabel + ".";
        }

        private void lvCommands_AfterLabelEdit(object sender, LabelEditEventArgs e) {
            lvCommands.SelectedItems.Clear();
            btnCmdAdd.Enabled = true;
            lvCommands.Items[e.Item].Selected = true;
            if (e.Label == null)
                return;
            UserEntryControl.GetEntry(m_OldLabel).Name = e.Label;
            LoadCommand(lvCommands.SelectedItems[0].Text);
            lblInfo.Text = "Edit command " + m_Current.Name + ".";
        }

        private void LoadCommand(string name) {
            foreach (XmlCommand cmd in CommandControl.CommandList)
                if (cmd.Name == name)
                    LoadCommand(cmd);
        }

        private void LoadCommand(XmlCommand command) {
            m_Current = command;

            txtCmdName.Text = command.Name;
            txtCmdFuncScript.Text = command.ScriptToCall;
            txtCmdFunction.Text = command.FunctionToCall;
            m_Flags = command.Requires.Flags;
            txtCmdFlags.Text = GetStringFromList(m_Flags);
            foreach (string alias in command.Aliases)
                lvCmdAliases.Items.Add(alias);
            txtCmdDescription.Text = command.Description;
        }

        private void SaveCurrentEntry() {
            m_Current.Function = txtCmdFuncScript.Text + "." + txtCmdFunction.Text;
            m_Current.Requires.Flags = m_Flags;
            m_Current.Aliases.Clear();
            foreach (ListViewItem item in lvCmdAliases.Items)
                m_Current.Aliases.Add(item.Text);
            m_Current.Description = txtCmdDescription.Text;

            //is name changed?
            if (txtCmdName.Text != m_Current.Name) {
                //yes? change the list then the command object
                foreach (ListViewItem item in lvCommands.Items) {
                    if (item.Text == m_Current.Name) {
                        //change command name in list
                        item.Text = txtCmdName.Text;
                    }
                }
                //change command name
                m_Current.Name = txtCmdName.Text;
            }

            CommandControl.Save();
        }

        private string GetStringFromList(List<string> list) {
            string l = "";
            foreach (string ll in list)
                l += ll + ", ";
            if (l != "")
                l = l.Substring(0, l.Length - 2);
            return l;
        }

        private void NewEntry() {
            string name = CommandControl.GetMakeName;
            XmlCommand command = CommandControl.MakeCommand(name);
            ListViewItem item = lvCommands.Items.Add(new ListViewItem(command.Name));
            item.Selected = true;
        }

        private void btnEntryAdd_Click(object sender, EventArgs e) {
            NewEntry();
        }

        private void btnEntryRemove_Click(object sender, EventArgs e) {
            foreach (ListViewItem item in lvCommands.SelectedItems) {
                CommandControl.RemoveEntry(CommandControl.GetEntry(item.Text));
                item.Remove();
            }
            btnCmdRemove.Enabled = false;
        }

        private void btnEntrySave_Click(object sender, EventArgs e) {
            SaveCurrentEntry();
            lvCommands.SelectedItems.Clear();
        }

        private void btnEntryCancel_Click(object sender, EventArgs e) {
            m_CommandSaved = true;
            lvCommands.SelectedItems.Clear();
        }

        private void btnOK_Click(object sender, EventArgs e) {
            SaveCurrentEntry();
            lvCommands.SelectedItems.Clear();
            this.Close();
        }

        private void btnCancel_Click(object sender, EventArgs e) {
            m_CommandSaved = true;
            lvCommands.SelectedItems.Clear();
            this.Close();
        }

        private void control_Enter(object sender, EventArgs e) {
            lblInfo.Text = tip.GetToolTip((Control) sender);
        }

        private void control_Changed(object sender, EventArgs e) {
            m_CommandSaved = false;
            btnCmdSave.Enabled = true;
        }

        private void btnCmdFlags_Click(object sender, EventArgs e) {
            new frmFlagsManager(this, m_Current).ShowDialog(this);
        }

        public void SetFlags(List<string> flags) {
            m_Flags = flags;
            txtCmdFlags.Text = GetStringFromList(m_Flags);
        }

        private void btnCmdAliasesAdd_Click(object sender, EventArgs e) {
            ListViewItem item = lvCmdAliases.Items.Add(new ListViewItem(""));
            item.BeginEdit();
        }

        private void btnCmdAliasesRemove_Click(object sender, EventArgs e) {
            foreach (ListViewItem item in lvCmdAliases.SelectedItems)
                item.Remove();
        }

        private void lvCmdAliases_SelectedIndexChanged(object sender, EventArgs e) {
            btnCmdAliasesRemove.Enabled = (lvCmdAliases.SelectedItems.Count > 0);
        }

        private void lvCmdAliases_BeforeLabelEdit(object sender, LabelEditEventArgs e) {
            btnCmdAliasesRemove.Enabled = false;
            btnCmdAliasesAdd.Enabled = false;
            m_OldLabel = lvCmdAliases.Items[e.Item].Text;
            lblInfo.Text = "Edit alias.";
        }

        private void lvCmdAliases_AfterLabelEdit(object sender, LabelEditEventArgs e) {
            lvCmdAliases.SelectedItems.Clear();
            btnCmdAliasesAdd.Enabled = true;
            lvCmdAliases.Items[e.Item].Selected = true;
            if (e.Label == null)
                return;
            lblInfo.Text = "Add, edit, or remove aliases.";
        }

        private void btnEditSyntax_Click(object sender, EventArgs e) {
            new frmSyntaxEditor(this, m_Current).ShowDialog(this);
        }
    }
}
